#include <iostream>
#include <string>
using namespace std;
class A
{
private:
    int n2;
    int n1;
 
public:
 
    A() :n2(34), n1(n2+1) {}
 
    void Print() {
        cout << "n1:" << n1 << ", n2: " << n2 << endl;
    }
};


#include <iostream>
#include <stdexcept>

struct TreeNode {
    int key;
    TreeNode* left;
    TreeNode* right;
    int height;

    TreeNode(int k) : key(k), left(nullptr), right(nullptr), height(1) {}
};

class AVLTree {
private:
    TreeNode* root;

    int height(TreeNode* node) {
        return node == nullptr ? 0 : node->height;
    }

    int max(int a, int b) {
        return (a > b) ? a : b;
    }

    TreeNode* rightRotate(TreeNode* y) {
        TreeNode* x = y->left;
        TreeNode* T2 = x->right;

        x->right = y;
        y->left = T2;

        y->height = max(height(y->left), height(y->right)) + 1;
        x->height = max(height(x->left), height(x->right)) + 1;

        return x;
    }

    TreeNode* leftRotate(TreeNode* x) {
        TreeNode* y = x->right;
        TreeNode* T2 = y->left;

        y->left = x;
        x->right = T2;

        x->height = max(height(x->left), height(x->right)) + 1;
        y->height = max(height(y->left), height(y->right)) + 1;

        return y;
    }

    int getBalance(TreeNode* node) {
        return node == nullptr ? 0 : height(node->left) - height(node->right);
    }

    TreeNode* insert(TreeNode* node, int key) {
        if (node == nullptr) {
            return new TreeNode(key);
        }

        if (key < node->key) {
            node->left = insert(node->left, key);
        } else if (key > node->key) {
            node->right = insert(node->right, key);
        } else {
            // Duplicate keys are not allowed in this implementation
            return node;
        }

        node->height = 1 + max(height(node->left), height(node->right));

        int balance = getBalance(node);

        // Left Left Case
        if (balance > 1 && key < node->left->key) {
            return rightRotate(node);
        }

        // Right Right Case
        if (balance < -1 && key > node->right->key) {
            return leftRotate(node);
        }

        // Left Right Case
        if (balance > 1 && key > node->left->key) {
            node->left = leftRotate(node->left);
            return rightRotate(node);
        }

        // Right Left Case
        if (balance < -1 && key < node->right->key) {
            node->right = rightRotate(node->right);
            return leftRotate(node);
        }

        return node;
    }

    void preOrder(TreeNode* root) {
        if (root != nullptr) {
            std::cout << root->key << " ";
            preOrder(root->left);
            preOrder(root->right);
        }
    }

public:
    AVLTree() : root(nullptr) {}

    void insert(int key) {
        root = insert(root, key);
    }

    void preOrder() {
        preOrder(root);
        std::cout << std::endl;
    }
};

 
int main()
{
 
    A a;
    a.Print();
    cout << 3 % 1 << endl;

    int arr[] = {10, 20, 30, 40, 50, 25};
    int n = sizeof(arr) / sizeof(arr[0]);

    AVLTree tree;

    for (int i = 0; i < n; ++i) {
        tree.insert(arr[i]);
    }

    tree.preOrder(); // Pre-order traversal of the constructed AVL tree

    return 0;

}